﻿using ArtMath.Attribute;
using ArtMath.Component.Interface;
using ArtMath.Component.Line;
using ArtMath.Component.Point;
using ArtMath.Core.Data;
using ArtMath.Core.Helper;
using ArtMath.PointCollection;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ArtMath.Component.Manager
{
    [Serializable]
    public abstract class TangentLinesManagerBase : ComponentManagerBase
    {
        List<TangentLine> lines = new List<TangentLine>();
        PointBase passPoint;
        LineBase curve;
        protected ICurveLike curInfo;
        public TangentLinesManagerBase(SketchPad pad, string name, LineBase cur, PointBase pt, bool addToList = true) : base(pad, name, ToolTypeName.qxglq, addToList)
        {
            Curve = cur;
            PassPoint = pt;
        }
        public override PointD MassPoint
        {
            get
            {
                return Utility.GetBaryCenter(Lines.Select((TangentLine line) => { return line.MassPoint; }).ToList());
            }
        }
        public override PointCollectionsManager Skeleton
        {
            get
            {
                PointCollectionsManager res = new PointCollectionsManager();
                foreach (TangentLine item in Lines)
                {
                    res.AddPointCollection(item.Skeleton);
                }
                return res;
            }
        }
        public override PointCollectionsManager PSkeleton
        {
            get
            {
                PointCollectionsManager res = new PointCollectionsManager();
                foreach (TangentLine item in Lines)
                {
                    res.AddPointCollection(item.PSkeleton);
                }
                return res;
            }
        }
        public override PointCollectionsManager NewSkeleton
        {
            get
            {
                PointCollectionsManager res = new PointCollectionsManager();
                foreach (TangentLine item in Lines)
                {
                    res.AddPointCollection(item.NewSkeleton);
                }
                return res;
            }
        }
        public override PointCollectionsManager NewPSkeleton
        {
            get
            {
                PointCollectionsManager res = new PointCollectionsManager();
                foreach (TangentLine item in Lines)
                {
                    res.AddPointCollection(item.NewPSkeleton);
                }
                return res;
            }
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("Curve")]
        public LineBase Curve
        {
            get { return curve; }
            set
            {
                if (curve != null)
                {
                    curInfo = null;
                    curve.ComponentManagers.Remove(this);
                }
                curve = value;
                if (curve != null)
                {
                    curInfo = curve as ICurveLike;
                    curve.ComponentManagers.Insert(0, this);
                }
            }
        }
        [MultilingualCategory("Structure"), MultilingualDisplayName("PassPoint")]
        public PointBase PassPoint
        {
            get { return passPoint; }
            set
            {
                passPoint?.ComponentManagers.Remove(this);
                passPoint = value;
                passPoint?.ComponentManagers.Insert(0, this);
            }
        }
        [MultilingualCategory("Parameter"), MultilingualDisplayName("TangentLine")]
        public List<TangentLine> Lines
        {
            get { return lines; }
        }
        public override void ForEachStraightLine(Predicate<StraightLineBase> act)
        {
            if (act == null) return;
            foreach (TangentLine item in Lines)
            {
                if (!act(item))
                {
                    break;
                }
            }
        }
        protected override void ForEachManagedComponent(Predicate<Base> act)
        {
            if (act == null) return;
            if (!act(Curve)) return;
            if (!act(PassPoint)) return;
        }
        public override void ForEachPoint(Predicate<PointBase> act)
        {
            if (act == null) return;
            if (!act(PassPoint)) return;
            foreach (TangentLine item in Lines)
            {
                if (!act(item.TangentPoint))
                {
                    break;
                }
            }
        }
        public override PointD AnchorPoint(PropertyDisplayer disp)
        {
            return PassPoint.Pxy;
        }
        public override void InChildrenIterator(Predicate<ShapeBase> act)
        {
            if (act == null) return;
            foreach (TangentLine item in Lines)
            {
                if (item == null) continue;
                if (!act(item)) break;
            }
        }
        //public override HashSet<Base> GetRelatedObject()
        //{
        //    HashSet<Base> set = new HashSet<Base>();
        //    foreach (TangentLine item in Lines)
        //    {
        //        if (!item.GlobalFlag)
        //        {
        //            set.AddRange(item.GetRelatedObject());
        //        }
        //    }
        //    return set;
        //}
    }
}
